﻿#include "IMysql.h"
#include <QThread>
#include <QSqlQuery>
#include <QDebug>
#include <QProcess>
#include <QSqlError>

IMysql::IMysql(QObject* parent): IDatabase(parent)
{
    mTimerReconnect = new QTimer(this);
    QObject::connect(mTimerReconnect, &QTimer::timeout, this, &IMysql::reconnect);
}

IMysql::IMysql(const SqlLinkParam &par, QObject *parent): IDatabase(par, parent)
{
    mTimerReconnect = new QTimer(this);
    QObject::connect(mTimerReconnect, &QTimer::timeout, this, &IMysql::reconnect);
}

bool IMysql::init()
{
    if(connect()){
        setSqlState(SS_Valid);
        if(!createDatabase()){
            qDebug() << "sb";
            setSqlError(SE_CreateDB);
            mErrMsg = mDb.lastError().text();
            return false;
        }
        if(!createTable()){
            setSqlError(SE_CreateTB);
            mErrMsg = mDb.lastError().text();
            return false;
        }
    } else {
        setSqlState(SS_Invalid);
        return false;
    }
    return true;
}

void IMysql::setSqlState(SqlState state)
{
    if(state == mState)
        return;
    mState = state;
    if(mState == SS_Invalid){
        mTimerReconnect->start(2000);
    } else if(mState == SS_Valid){
        mTimerReconnect->stop();
    }
}

bool IMysql::connect()
{
    mDb = QSqlDatabase::addDatabase("QMYSQL", mLinkPar.linkName);
    mDb.setHostName(mLinkPar.ip);
    mDb.setPort(mLinkPar.port);
    mDb.setUserName(mLinkPar.user);
    mDb.setPassword(mLinkPar.password);
    if(!mDb.open()){
        qDebug() << "fail to open mysql:" + mDb.lastError().text();
        return false;
    }
    return true;
}

bool IMysql::createDatabase()
{
    QSqlQuery query(mDb);
    QString sqlStatement = "CREATE DATABASE IF NOT EXISTS " + mLinkPar.dbName;
    if (!query.exec(sqlStatement)){
        qDebug() << query.lastError().text() << sqlStatement;
        return false;
    }
    mDb.setDatabaseName(mLinkPar.dbName);
    if(!mDb.open()){
        qDebug() << "fail to open Database:" + mDb.lastError().text();
        return false;
    }
    return true;
}

bool IMysql::createTable()
{
    QSqlQuery query(mDb);
    QString sqlStatement = QString("CREATE TABLE IF NOT EXISTS %1 "
                                   "(%2 varchar(256) primary key, "
                                   "%3 varchar(30), "
                                   "%4 varchar(30), "
                                   "%5 text not null)").arg(mLinkPar.tableName,
                                    DBUuid, DBCreatTime, DBModifyTime, DBJson);
    if(!query.exec(sqlStatement)){
        qDebug() << query.lastError().text() << sqlStatement;
        return false;
    }
    return false;
}

bool IMysql::checkIpStatus()
{
    QProcess cmd;
    QString command = "";
#ifdef Q_OS_WIN
    /// -n 要发送的回显请求数
    /// -w 等待每次回复的超时时间(毫秒)
    command = QString("ping %1 -n 1 -w 1000").arg(mLinkPar.ip);
#else \
    /// -s ping发送的字节数 \
    /// -c ping的次数
    command = QString("ping -s 1 -c 1 %1").arg(ip);
#endif
    cmd.start(command);
    cmd.waitForFinished(1000 * 1);

    QString retStr = cmd.readAll();
    if (retStr.indexOf("ttl", 0, Qt::CaseInsensitive) == -1) {
        return false;
    }
    return true;
}

bool IMysql::checkSqlEnable()
{
    QSqlQuery query(mDb);
    QString command = "select 1";

    QTime startTime = QTime::currentTime();
    if (query.exec(command)) {
        return true;
    }

    QTime endTime = QTime::currentTime();
    qDebug() << "检测心跳断开耗时：" << startTime.msecsTo(endTime) << "ms";
    return false;
}

void IMysql::reconnect()
{
    if(!checkIpStatus())
        return;
    init();
}
